<template>
  <div class="my-form">
    <!-- {{ formData }} -->
    <el-form
      ref="refElForm"
      :model="formData"
      v-bind="$attrs"
      :scroll-to-error="true"
      label-suffix=":"
      label-width="auto"
      @keyup.enter="onsubmit"
    >
      <el-form-item
        v-for="(item, index) in formItem"
        :key="item.key"
        :style="{ width: item?.elementConfig?.textareaWidth }"
        :label="item.name"
        :prop="item.key"
        :class="item?.elementConfig?.class"
        :rules="getRules(item.verificationData)"
      >
        <div v-if="item.formType == 'info'">: {{ item.value }}</div>
        <div v-if="item.formType == 'component'">
          <component :is="item.elementConfig.component" :item="item" />
        </div>
        <div v-if="item.formType == 'empty'" />
        <!-- 人员多选框 value 类型为数组 -->
        <div v-if="item.formType == 'dialog-multiple'" class="flex items-center gap-3">
          <div class="flex gap-2 flex-wrap">
            <el-tag v-for="(obj, index) in item.value" :key="obj.name" @close="onCloseTag(item.value, index)">
              {{ obj.name || obj.userName }}
            </el-tag>
          </div>
          <el-button
            :disabled="item.elementConfig.disabled"
            link
            size="large"
            type="primary"
            @click="openDialog(item, index)"
          >
            <span>请选择</span>
          </el-button>
        </div>
        <div v-if="item.formType == 'dialog'">
          <!-- {{ item.value }} -->
          <el-button
            link
            size="large"
            type="primary"
            :disabled="item.elementConfig.disabled"
            @click="openDialog(item, index)"
          >
            <span v-if="item.value?.name">{{ item.value?.name }}</span>
            <span v-else>{{ '请选择' }}</span>
          </el-button>
          <span :style="{ pointerEvents: item.elementConfig.disabled ? 'none' : 'auto' }">
            <svg-icon v-if="item.value?.name" icon-class="删除" class="on-del" @click="onDelSelect(item)" />
          </span>
        </div>
        <el-tree
          v-if="item.formType == 'el-tree'"
          v-model="item.value"
          style="width: 100%"
          :data="item.elementConfig.data"
          node-key="name"
          multiple
          :render-after-expand="false"
          show-checkbox
          :props="{
            children: 'children',
            label: 'name'
          }"
          :default-checked-keys="item.elementConfig.defaultCheckedKeys"
        />
        <el-cascader
          v-if="item.formType == 'el-cascader'"
          v-model="item.value"
          style="width: 100%"
          :options="item.elementConfig.options"
          :props="item.elementConfig.props"
          :placeholder="getPlaceholder(item)"
          filterable
          clearable
        />

        <el-cascader-panel
          v-if="item.formType == 'el-cascader-panel'"
          v-model="item.value"
          :options="item.elementConfig.options"
          :props="item.elementConfig.props"
        />

        <el-input-number
          v-if="item.formType == 'input-number'"
          v-model="item.value"
          style="width: 100%"
          clearable
          :controls-position="item.elementConfig.position || 'right'"
          :min="item.elementConfig.min"
          :max="item.elementConfig.max"
          :step="item.elementConfig.step"
        />
        <el-input
          v-if="item.formType == 'input-val-number'"
          v-model.number="item.value"
          clearable
          :placeholder="getPlaceholder(item)"
        >
          <template v-if="item.elementConfig.suffix" #suffix>
            {{ item.elementConfig.suffix }}
          </template>
        </el-input>
        <div v-if="item.formType == 'many-input'" class="many-input-box">
          <!-- {{ item.value }} -->
          <el-input
            v-for="(val, index) in item.elementConfig.manyInputLength"
            :key="index"
            v-model.trim="item.value[index]"
            class="mb-1"
            clearable
          >
            <template #append>
              <el-button v-if="index == 0" circle :icon="Plus" @click="onAddInput(item)" />
              <el-button v-if="index !== 0" circle :icon="Minus" @click="onDelInput(item, index)" />
            </template>
          </el-input>
        </div>
        <el-input
          v-if="item.formType == 'input'"
          v-model.trim="item.value"
          clearable
          :placeholder="getPlaceholder(item)"
          :type="item.elementConfig.type ?? 'text'"
          :rows="item.elementConfig.rows"
          :disabled="item.elementConfig.disabled"
        >
          <template v-if="item.elementConfig.prepend" #prepend>
            {{ item.elementConfig.prepend }}
          </template>
          <template v-if="item.elementConfig.button" #append>
            <el-button type="primary" @click="onPrepend(item)">
              {{ item.elementConfig.button }}
            </el-button>
          </template>
          <template v-if="item.elementConfig.suffix" #suffix>
            {{ item.elementConfig.suffix }}
          </template>
        </el-input>
        <el-select
          v-if="item.formType == 'select'"
          v-model="item.value"
          clearable
          filterable
          style="width: 100%"
          :placeholder="getPlaceholder(item)"
          :disabled="item.elementConfig.disabled"
          :multiple="item.elementConfig.multiple"
        >
          <el-option
            v-for="childrenItem in item.elementConfig.options"
            :key="childrenItem.key"
            :label="childrenItem.value"
            :value="childrenItem.key"
          />
        </el-select>
        <el-date-picker
          v-if="item.formType === 'year'"
          v-model="item.value"
          style="width: 100%"
          value-format="YYYY"
          clearable
          type="year"
          :placeholder="getPlaceholder(item)"
        />
        <el-date-picker
          v-if="item.formType == 'month'"
          v-model="item.value"
          style="width: 100%"
          type="month"
          :format="item.elementConfig?.valueFormat || 'YYYY-MM'"
          :value-format="item.elementConfig?.valueFormat || 'YYYY-MM'"
          :placeholder="getPlaceholder(item)"
          clearable
        />
        <el-date-picker
          v-if="item.formType == 'date'"
          v-model="item.value"
          style="width: 100%"
          type="date"
          value-format="YYYY-MM-DD"
          :placeholder="getPlaceholder(item)"
          :disabled="item.elementConfig.disabled"
          clearable
        />
        <el-date-picker
          v-if="item.formType == 'date-range'"
          v-model="item.value"
          style="width: 100%"
          type="daterange"
          value-format="YYYY-MM-DD"
          range-separator="至"
          start-placeholder="起始"
          end-placeholder="结束"
          :placeholder="getPlaceholder(item)"
          :disabled="item.elementConfig.disabled"
          clearable
        />
        <el-date-picker
          v-if="item.formType == 'date-datetime'"
          v-model="item.value"
          style="width: 100%"
          type="datetime"
          :disabled="item.elementConfig.disabled"
          :placeholder="getPlaceholder(item)"
          format="YYYY-MM-DD hh:mm:ss"
          value-format="YYYY-MM-DD HH:mm:ss"
        />
        <el-date-picker
          v-if="item.formType == 'date-datetimerange'"
          v-model="item.value"
          style="width: 100%"
          :disabled="item.elementConfig.disabled"
          type="datetimerange"
          start-placeholder="起始时间"
          end-placeholder="结束时间"
          format="YYYY-MM-DD hh:mm:ss"
          value-format="YYYY-MM-DD HH:mm:ss"
        />
        <el-radio-group v-if="item.formType == 'radio'" v-model="item.value">
          <el-radio v-for="childrenItem in item.elementConfig.options" :label="childrenItem.value">
            {{ childrenItem.label }}
          </el-radio>
        </el-radio-group>
      </el-form-item>
      <slot name="customForm" :form-data="formData" />
    </el-form>
  </div>
</template>

<script setup lang="ts">
import { Minus, Plus } from '@element-plus/icons-vue'
import type { PropType } from 'vue'
import type { CL_FORM } from './type'
import { computed, ref } from 'vue'
import { formRules } from './data'

const props = defineProps({
  formItem: {
    required: true,
    type: Array as PropType<CL_FORM[]>
  }
})
const onAddInput = (item) => {
  item.elementConfig.manyInputLength++
  item.value.push('')
}
const onDelInput = (item, index) => {
  item.elementConfig.manyInputLength--
  item.value.splice(index, 1)
}
const onCloseTag = (list, index) => {
  list.splice(index, 1)
}
const onDelSelect = (item) => {
  item.value = null
  $emit('clear-dialog-val', item)
}
const openDialog = (item, index) => {
  $emit('open-dialog', item, index)
}
// 双向绑定数据
let $emit = defineEmits(['sent-form-data', 'on-change-select', 'on-prepend', 'open-dialog', 'clear-dialog-val'])

// patch 后缀点击打开弹框
const onPrepend = (item) => {
  $emit('on-prepend', item)
}
const refElForm = ref<any>(null)
const onsubmit = async () => {
  try {
    const flag = await refElForm.value.validate()
    if (flag) {
      $emit('sent-form-data', formData.value)
    }
  } catch (error) {
    console.error('表单数据不通过👉👉👉', error)
  }
}

const onRest = () => {
  refElForm.value.resetFields()
}
const formData = computed(() => {
  const obj = {}
  props.formItem.forEach((element) => {
    obj[element.key] = element.value
  })
  return obj
})
// 获取 简易 认证
const getRules = (item) => {
  if (typeof item === 'string') {
    return formRules[item]
  }
  return item
}
// 默认 文本
const getPlaceholder = (item) => {
  if (item.formType == 'input' || item.formType == 'input-area') {
    return `请输入${item.name}`
  } else {
    return `请选择${item.name}`
  }
}

defineExpose({ onsubmit, onRest, formData })
</script>

<style scoped lang="scss">
.on-del {
  cursor: pointer;
  margin-left: 3px;
}

.my-form {
  width: 100%;
}

:deep(.el-form-item__label) {
  line-height: 37px;
  font-weight: 400;
  font-size: 14px;
  color: rgba(0, 0, 0, 0.88);
}
</style>
